package com.neusoft.neuiotms.support.mongo.repository.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.neuiotms.support.mongo.model.LogDocument;
import com.neusoft.neuiotms.support.mongo.repository.CustomizedLogRepository;

public class CustomizedLogRepositoryImpl implements CustomizedLogRepository {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public List<LogDocument> search(Searchable searchable) {
        final Query query = new Query();
        final List<Criteria> criterias = this.buildWhere(searchable);
        criterias.forEach(it -> query.addCriteria(it));
        query.with(new Sort(Sort.Direction.DESC, "time"));
        return this.mongoTemplate.find(query, LogDocument.class);
    }

    @Override
    public Page<LogDocument> search(Pageable pageable, Searchable searchable) {
        return null;
    }

    private List<Criteria> buildWhere(final Searchable searchable) {
        final List<Criteria> criterias = new ArrayList<>();
        if (!StringUtils.isEmpty(searchable.getStrValue("app"))) {
            criterias.add(Criteria.where("app").is(searchable.getStrValue("app")));
        }
        if (!StringUtils.isEmpty(searchable.getStrValue("account"))) {
            criterias.add(Criteria.where("account").is(searchable.getStrValue("account")));
        }
        if (!StringUtils.isEmpty(searchable.getStrValue("username"))) {
            criterias.add(Criteria.where("username").regex(searchable.getStrValue("username")));
        }
        if (!StringUtils.isEmpty(searchable.getStrValue("ip"))) {
            criterias.add(Criteria.where("ip").regex(searchable.getStrValue("ip")));
        }
        if (!StringUtils.isEmpty(searchable.getStrValue("operation"))) {
            criterias.add(Criteria.where("operation").regex(searchable.getStrValue("operation")));
        }
        if (!StringUtils.isEmpty(searchable.getStrValue("api"))) {
            criterias.add(Criteria.where("api").regex(searchable.getStrValue("api")));
        }
        if (!StringUtils.isEmpty(searchable.getStrValue("extra"))) {
            criterias.add(Criteria.where("extra").regex(searchable.getStrValue("extra")));
        }

        final Long startTime = searchable.getLongValue("startTime");
        final Long endTime = searchable.getLongValue("endTime");
        if ((null != startTime) || (null != endTime)) {
            if ((null != startTime) && (null == endTime)) {
                criterias.add(Criteria.where("time").gte(startTime));
            } else if ((null == startTime) && (null != endTime)) {
                criterias.add(Criteria.where("time").lte(endTime));
            } else {
                criterias.add(Criteria.where("time").gte(startTime).lte(endTime));
            }

        }

        return criterias;
    }
}
